#include <iostream>
#include <cassert>

template<typename T>
class MyVector
{
public:
    MyVector(int size = 10);
    ~MyVector();

    // 访问
    T& at(int index) const;
    T& front() const;
    T& back() const;
    T& operator[](int index);

    // 容量
    bool empty() const;
    int size() const;
    int capacity() const;

    // 修改
    void clear();
    void insert(int index, const T& d);
    void remove(int index);
    void push_back(const T& d);
    void pop_back();

private:
    void alloc();
    void release();

private:
    T* data;
    int length;
    int current_pos;
};

template<typename T>
MyVector<T>::MyVector(int size) : data(nullptr), length(size), current_pos(0)
{
    release();
    data = new T[length];
}

template<typename T>
void MyVector<T>::alloc()
{
    if(current_pos == length) {
        // 1. 重新申请内存
        T* temp = new T[length + 10];
        length += 10;

        // 2. 把原有的数据复制到新内存中
        memcpy(temp, data, length * sizeof(T));
        
        // 3. 将原来内存空间释放
        release();
        data = temp;
    }
}

template<typename T>
void MyVector<T>::release()
{
    if(data != nullptr) {
        delete [] data;
        data = nullptr;
    }
}

template<typename T>
MyVector<T>::~MyVector()
{
    release();
}

template<typename T>
T& MyVector<T>::at(int index) const
{
    assert(index >= 0 && index < current_pos);
    return data[index];
}

template<typename T>
T& MyVector<T>::front() const
{
    assert(current_pos > 0);
    return data[0];
}

template<typename T>
T& MyVector<T>::back() const
{
    assert(current_pos > 0);
    return data[current_pos - 1];
}

template<typename T>
T& MyVector<T>::operator[](int index)
{
    assert(index >= 0 && current_pos > index);
    return data[index];
}

template<typename T>
bool MyVector<T>::empty() const
{
    if(current_pos == 0)
        return true;
    else
        return false;
}

template<typename T>
int MyVector<T>::size() const
{
    return current_pos;
}

template<typename T>
int MyVector<T>::capacity() const
{
    return length;
}

template<typename T>
void MyVector<T>::clear()
{
    current_pos = 0;
}

template<typename T>
void MyVector<T>::insert(int index, const T& d)
{
    assert(index >= 0 && index < current_pos);
    alloc();
    // if(current_pos == length) {
    //     // 1. 重新申请内存
    //     T* temp = new T[length + 10];
    //     length += 10;

    //     // 2. 把原有的数据复制到新内存中
    //     memcpy(temp, data, length * sizeof(T));
        
    //     // 3. 将原来内存空间释放
    //     release();
    //     data = temp;
    // }
    // 4. 插入到尾部
    if(index == current_pos - 1) {
        push_back(d);
    }

    // 5. 将插入数据节点后移
    memcpy(data + index + 1, data + index, (current_pos - index) * sizeof(T));

    // 6. 插入数据
    data[index] = d;
    current_pos += 1;
}

template<typename T>
void MyVector<T>::remove(int index)
{
    assert(index >= 0 && index < current_pos);
    // 1. 检查是否删除最后一个数据
    if(index == current_pos - 1) {
        pop_back();
    }

    // 2. 将内存往前移动一个数据空间
    memcpy(data + index, data + index + 1, (current_pos - index) * sizeof(T));
    --current_pos;
}

template<typename T>
void MyVector<T>::push_back(const T& d)
{
    alloc();

    data[current_pos] = d;
    ++ current_pos;
}

template<typename T>
void MyVector<T>::pop_back()
{
    assert(current_pos > 0);
    --current_pos;
}